﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Game.geodata;
using Game.model;
using java.lang;
using java.util;

namespace Game.ai
{
    public class PlayerAI:PlayableAI
{
	/**
	 * Constructor for PlayerAI.
	 * @param actor Player
	 */
	public PlayerAI(Player actor):base(actor)
	{
		//super(actor);
	}
	
	/**
	 * Method onIntentionRest.
	 */
	
	protected override void onIntentionRest()
	{
		changeIntention(CtrlIntention.AI_INTENTION_REST, null, null);
		setAttackTarget(null);
		clientStopMoving();
	}
	
	/**
	 * Method onIntentionActive.
	 */
	
	protected override void onIntentionActive()
	{
		clearNextAction();
		changeIntention(CtrlIntention.AI_INTENTION_ACTIVE, null, null);
	}
	
	/**
	 * Method onIntentionInteract.
	 * @param object GameObject
	 */

        protected override void onIntentionInteract(GameObject obj)
	{
		Player actor = getActor();
		if (actor.getSittingTask())
		{
			setNextAction(nextAction.INTERACT, obj, null, false, false);
			return;
		}
		else if (actor.isSitting())
		{
			actor.sendPacket(Msg.YOU_CANNOT_MOVE_WHILE_SITTING);
			clientActionFailed();
			return;
		}
		base.onIntentionInteract(obj);
	}
	
	/**
	 * Method onIntentionPickUp.
	 * @param object GameObject
	 */
	
	public override void onIntentionPickUp(GameObject obj)
	{
		Player actor = getActor();
		if (actor.getSittingTask())
		{
			setNextAction(nextAction.PICKUP, obj, null, false, false);
			return;
		}
		else if (actor.isSitting())
		{
			actor.sendPacket(Msg.YOU_CANNOT_MOVE_WHILE_SITTING);
			clientActionFailed();
			return;
		}
		base.onIntentionPickUp(obj);
	}
	
	/**
	 * Method onEvtForgetObject.
	 * @param object GameObject
	 */
	
	protected override void onEvtForgetObject(GameObject obj)
	{
		if (obj == null)
		{
			return;
		}
		base.onEvtForgetObject(obj);
		foreach (Summon summon in getActor().getSummonList())
		{
			summon.getAI().notifyEvent(CtrlEvent.EVT_FORGET_OBJECT, obj);
		}
	}
	
	/**
	 * Method thinkAttack.
	 * @param checkRange boolean
	 */
	
	protected override void thinkAttack(bool checkRange)
	{
		Player actor = getActor();
		if (actor.isInFlyingTransform())
		{
			setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
			return;
		}
		FlagItemAttachment attachment = actor.getActiveWeaponFlagAttachment();
		if ((attachment != null) && !attachment.canAttack(actor))
		{
			setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
			actor.sendActionFailed();
			return;
		}
		if (actor.isFrozen())
		{
			setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
			actor.sendPacket(SystemMsg.YOU_CANNOT_MOVE_WHILE_FROZEN, ActionFail.STATIC);
			return;
		}
		base.thinkAttack(checkRange);
	}
	
	/**
	 * Method thinkCast.
	 * @param checkRange boolean
	 */
	
	protected override void thinkCast(bool checkRange)
	{
		Player actor = getActor();
		FlagItemAttachment attachment = actor.getActiveWeaponFlagAttachment();
		if ((attachment != null) && !attachment.canCast(actor, _skill))
		{
			setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
			actor.sendActionFailed();
			return;
		}
		if (actor.isFrozen())
		{
			setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
			actor.sendPacket(SystemMsg.YOU_CANNOT_MOVE_WHILE_FROZEN, ActionFail.STATIC);
			return;
		}
		base.thinkCast(checkRange);
	}
	
	/**
	 * Method thinkCoupleAction.
	 * @param target Player
	 * @param socialId Integer
	 * @param cancel boolean
	 */
	
	protected void thinkCoupleAction(Player target, int socialId, bool cancel)
	{
		Player actor = getActor();
		if ((target == null) || !target.isOnline())
		{
			actor.sendPacket(Msg.COUPLE_ACTION_WAS_CANCELED);
			return;
		}
		if (cancel || !actor.isInRange(target, 50) || actor.isInRange(target, 20) || (actor.getReflection() != target.getReflection()) || !GeoEngine.canSeeTarget(actor, target, false))
		{
			target.sendPacket(Msg.COUPLE_ACTION_WAS_CANCELED);
			actor.sendPacket(Msg.COUPLE_ACTION_WAS_CANCELED);
			return;
		}
		if (_forceUse)
		{
			target.getAI().setIntention(CtrlIntention.AI_INTENTION_COUPLE_ACTION, actor, socialId);
		}
		int heading = actor.calcHeading(target.getX(), target.getY());
		actor.setHeading(heading);
		actor.broadcastPacket(new ExRotation(actor.getObjectId(), heading));
		actor.broadcastPacket(new SocialAction(actor.getObjectId(), socialId));
	}
	
	/**
	 * Method Attack.
	 * @param target GameObject
	 * @param forceUse boolean
	 * @param dontMove boolean
	 */
	
	public override void Attack(GameObject target, bool forceUse, bool dontMove)
	{
		Player actor = getActor();
		if (actor.isInFlyingTransform())
		{
			actor.sendActionFailed();
			return;
		}
		if ((java
            .lang.System.currentTimeMillis() - actor.getLastAttackPacket()) < Config.ATTACK_PACKET_DELAY)
		{
			actor.sendActionFailed();
			return;
		}
		actor.setLastAttackPacket();
		if (actor.getSittingTask())
		{
			setNextAction(nextAction.ATTACK, target, null, forceUse, false);
			return;
		}
		else if (actor.isSitting())
		{
			actor.sendPacket(Msg.YOU_CANNOT_MOVE_WHILE_SITTING);
			clientActionFailed();
			return;
		}
		base.Attack(target, forceUse, dontMove);
	}
	
	/**
	 * Method Cast.
	 * @param skill Skill
	 * @param target Creature
	 * @param forceUse boolean
	 * @param dontMove boolean
	 */
	
	public override void Cast(Skill skill, Creature target, bool forceUse, bool dontMove)
	{
		Player actor = getActor();
		if (!skill.altUse() && !skill.isToggle() && !((skill.getSkillType() == SkillType.CRAFT) && Config.ALLOW_TALK_WHILE_SITTING))
		{
			if (actor.getSittingTask())
			{
				setNextAction(nextAction.CAST, skill, target, forceUse, dontMove);
				clientActionFailed();
				return;
			}
			else if ((skill.getSkillType() == SkillType.SUMMON) && (actor.getPrivateStoreType() != Player.STORE_PRIVATE_NONE))
			{
				actor.sendPacket(Msg.YOU_CANNOT_SUMMON_DURING_A_TRADE_OR_WHILE_USING_THE_PRIVATE_SHOPS);
				clientActionFailed();
				return;
			}
			else if (actor.isSitting())
			{
			    actor.sendPacket(skill.getSkillType() == SkillType.TRANSFORMATION
			                         ? Msg.YOU_CANNOT_TRANSFORM_WHILE_SITTING
			                         : Msg.YOU_CANNOT_MOVE_WHILE_SITTING);
			    clientActionFailed();
				return;
			}
		}
		base.Cast(skill, target, forceUse, dontMove);
	}
	
	/**
	 * Method onEvtAttacked.
	 * @param attacker Creature
	 * @param damage int
	 */
	
	protected override void onEvtAttacked(Creature attacker, int damage)
	{
		Player actor = getActor();
		if (attacker != null && actor.getSummonList().size() > 0)
		{
			List servitors = actor.getSummonList().getServitors();
			foreach (Summon summon in (IEnumerable)servitors)
			{
				if (!summon.isDead() && summon.isDefendMode() && !summon.isDepressed())
				{
					summon.getAI().Attack(attacker, false, false);
				}
			}
		}
		base.onEvtAttacked(attacker, damage);
	}

	/**
	 * Method getActor.
	 * @return Player
	 */
	
	public override Player getActor()
	{
		return (Player) base.getActor();
	}
}

}
